package org.xxpay.pay.mq;

import com.alibaba.fastjson.JSONObject;
import org.apache.activemq.ScheduledMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Component;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.common.util.JsonUtil;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.common.util.XXPayUtil;
import org.xxpay.core.entity.MchAgentpayRecord;
import org.xxpay.core.service.IXxPayAgentpayService;
import org.xxpay.pay.service.CommonService;

import javax.jms.*;

@Component
public class Mq4AgentpayMchConfirm {

    @Autowired
    private Queue agentpayMchConfirmQueue;

    @Autowired
    private JmsTemplate jmsTemplate;

    @Autowired
    private CommonService commonService;

    @Autowired
    private IXxPayAgentpayService xxPayAgentpayService;

    private static final MyLog _log = MyLog.getLog(Mq4AgentpayMchConfirm.class);

    public void send(String agentpayOrderId, String apiConfirmJson, int count, int delay) {

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("agentpayOrderId", agentpayOrderId);
        jsonObject.put("apiConfirmJson", apiConfirmJson);
        jsonObject.put("count", count);

        _log.info("发送MQ延时消息:msg={},delay={}", jsonObject.toJSONString(), delay);
        jmsTemplate.send(this.agentpayMchConfirmQueue, new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                TextMessage tm = session.createTextMessage(jsonObject.toJSONString());
                tm.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);
                tm.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, 1);
                return tm;
            }
        });
    }

    @JmsListener(destination = MqConfig.AGENTPAY_MCH_CONFIRM_QUEUE_NAME)
    public void receive(String msg) {
        _log.info("接收代付订单二次确认接口请求.agentpayOrderId={}", msg);

        JSONObject jsonObject = JSONObject.parseObject(msg);
        String agentpayOrderId = jsonObject.getString("agentpayOrderId");
        String apiConfirmJson = jsonObject.getString("apiConfirmJson");
        Integer count = jsonObject.getInteger("count");
        JSONObject confirmJson = JsonUtil.getJSONObjectFromJson(apiConfirmJson);

        //查询出代付订单
        MchAgentpayRecord record = commonService.mchAgentpayService.findByAgentpayOrderId(agentpayOrderId);
        if(record == null || record.getStatus() != PayConstant.AGENTPAY_STATUS_WAIT_API_CONFIRM){ //代付订单状态异常
            _log.error("发送二次确认订单状态异常： agentpayOrderId={}, currentStatus={}", agentpayOrderId, record.getStatus());
            return ;
        }

        String resp = "";
        try {
            //发送确认请求
            resp = XXPayUtil.call4Post(record.getMchConfirmReqUrl());

        } catch (Exception e) {
            resp = "【请求商户二次确认接口异常】 err= " + e.getMessage();
        }

        boolean isEffectiveResp = false;  //是否为有效的相应
        if(confirmJson.getString("notifySuccessStatus").equalsIgnoreCase(resp)){ //商户已确认该订单， 继续执行

            //推动订单继续执行
            xxPayAgentpayService.mchConfirmNext(agentpayOrderId);
            isEffectiveResp = true;

        }else if(confirmJson.getString("notifyFailStatus").equalsIgnoreCase(resp)){ //商户明确订单不存在， 应改为订单失败

            //更新订单为失败， 并退还商户冻结资金
            xxPayAgentpayService.auditReject(record, PayConstant.AGENTPAY_STATUS_WAIT_API_CONFIRM);
            isEffectiveResp = true;

        }else{ //未知结果， 继续下一次尝试执行
        }

        //更新订单响应结果
        commonService.mchAgentpayService.updateMchConfirmResp(agentpayOrderId, resp);

        _log.info("商户二次确认订单完成， agentpayOrderId={}, 结果：{}", agentpayOrderId, resp);

        //不是有效的响应结果， 需要继续执行
        if(!isEffectiveResp){

            if(count++ <= 3) {  //最多执行三次
                send(agentpayOrderId, apiConfirmJson, count, 10 * 1000); //延迟10秒，继续发送
            }else{
                _log.error("商户二次确认订单超过最大次数，更新为失败！ agentpayOrderId ={}", agentpayOrderId);
                //更新订单为失败， 并退还商户冻结资金
                xxPayAgentpayService.auditReject(record, PayConstant.AGENTPAY_STATUS_WAIT_API_CONFIRM);
            }
        }

    }
}
